﻿using System;
using System.Collections.Generic;
using MiniJSON;

namespace FacePP
{
    /// <summary>
    /// person manager
    /// </summary>
    public interface IPersonInfoManager
    {
       /// <summary>
        /// 创建一个Person
       /// </summary>
        /// <param name="face_ids">face_id 集合</param>
        /// <param name="group_ids">group id 列表</param>
        /// <param name="person_name">Person的Name信息，必须在App中全局唯一。Name不能包含^@,&=*'"等非法字符，且长度不得超过255。Name也可以不指定，此时系统将产生一个随机的name。</param>
       /// <param name="tag"></param>
       /// <returns></returns>
        IPersonCreated Create_InfoFromId(string[] face_ids, string[] group_ids, string person_name = "", string tag = "");
        /// <summary>
        /// 创建一个Person
        /// </summary>
        /// <param name="face_ids">face_id 集合</param>
        /// <param name="group_names">group name 列表</param>
        /// <param name="person_name">Person的Name信息，必须在App中全局唯一。Name不能包含^@,&=*'"等非法字符，且长度不得超过255。Name也可以不指定，此时系统将产生一个随机的name。</param>
        /// <param name="tag"></param>
        /// <returns></returns>
        IPersonCreated Create_InfoFromName(string[] face_ids, string[] group_names, string person_name = "", string tag = "");
       
        /// <summary>
        /// 删除一组Person
        /// </summary>
        /// <param name="person_names">Person name 列表</param>
        /// <returns></returns>
        IDeleteState Detele_FromName(string[] person_names);
        /// <summary>
        /// 删除一组Person
        /// </summary>
        /// <param name="person_ids">Person id 列表</param>
        /// <returns></returns>
        IDeleteState Detele_FromId(string[] person_ids);

        /// <summary>
        /// 将一组Face加入到一个Person中。注意，一个Face只能被加入到一个Person中。(一个Person最多允许包含10000个Face)
        /// </summary>
        /// <param name="person_name">Person name列表</param>
        /// <param name="face_ids">要加入的face 集合 </param>
        /// <returns></returns>
        IAddedState Added_FromName(string person_name, string[] face_ids);
        /// <summary>
        /// 将一组Face加入到一个Person中。注意，一个Face只能被加入到一个Person中。(一个Person最多允许包含10000个Face)
        /// </summary>
        /// <param name="person_id">Person id 列表</param>
        /// <param name="face_ids">要加入的face 集合</param>
        /// <returns></returns>
        IAddedState Added_FromId(string person_id, string[] face_ids);

        /// <summary>
        /// 删除Person中的一个或多个Face
        /// </summary>
        /// <param name="person_name"></param>
        /// <param name="face_ids">要删除的face列表</param>
        /// <returns></returns>
        IRemovedState Removed_FromName(string person_name, string[] face_ids);
        /// <summary>
        ///  删除Person中的 全部face
        /// </summary>
        /// <param name="person_name"></param>
        /// <returns></returns>
        IRemovedState Removed_FromName(string person_name);
        /// <summary>
        /// 删除Person中的一个或多个Face
        /// </summary>
        /// <param name="person_id"></param>
        /// <param name="face_ids">要删除的face列表</param>
        /// <returns></returns>
        IRemovedState Removed_FromId(string person_id, string[] face_ids);
        /// <summary>
        /// 删除Person中的 全部face
        /// </summary>
        /// <param name="person_id"></param>
        /// <returns></returns>
        IRemovedState Removed_FromId(string person_id);

        /// <summary>
        /// 设置Person的name和tag
        /// </summary>
        /// <param name="person_id"></param>
        /// <param name="name">新的name</param>
        /// <param name="tag">新的tag</param>
        /// <returns></returns>
        IPerson SetInfo_FromId(string person_id, string name = "", string tag = "");
        /// <summary>
        /// 设置Person的name和tag
        /// </summary>
        /// <param name="person_name"></param>
        /// <param name="name">新的name</param>
        /// <param name="tag">新的tag</param>
        /// <returns></returns>
        IPerson SetInfo_FromName(string person_name, string name = "", string tag = "");

        /// <summary>
        /// 获取一个Person的信息, 包括name, id, tag, 相关的face, 以及groups等信息
        /// </summary>
        /// <param name="person_id"></param>
        /// <returns></returns>
        IPersonGetInfoed GetInfo_FromId(string person_id);
        /// <summary>
        /// 获取一个Person的信息, 包括name, id, tag, 相关的face, 以及groups等信息
        /// </summary>
        /// <param name="person_name"></param>
        /// <returns></returns>
        IPersonGetInfoed GetInfo_FromName(string person_name);
    }
    /// <summary>
    /// PersonInfoManager
    /// </summary>
    public class PersonInfoManager:IPersonInfoManager
    {
        private const string CREATE_URL = "https://apicn.faceplusplus.com/v2/person/create";
        private const string DELETE_URL = "https://apicn.faceplusplus.com/v2/person/delete";
        private const string ADD_URL = "https://apicn.faceplusplus.com/v2/person/add_face";
        private const string REMOVE_URL = "https://apicn.faceplusplus.com/v2/person/remove_face";
        private const string SETINFO_URL = "https://apicn.faceplusplus.com/v2/person/set_info";
        private const string GETINFO_URL = "https://apicn.faceplusplus.com/v2/person/get_info";

        private IPersonCreated create(string sendUrl)
        {
            try
            {
                string json = HttpHelper.CreateGetHttpText(sendUrl);
                object obj = Json.Deserialize(json);
                IPersonCreated info = new PersonCreated();
                info.CopyObject(obj as Dictionary<string, object>);
                return info;
            }
            catch (Exception)
            {
                
               // throw;
            }
            return null;
        }
        IPersonCreated Create_InfoFromId(string face_id = "", string group_id = "", string person_name = "", string tag = "")
        {
            string sendUrl = CREATE_URL + "?api_key=" + Facepp_config.api_key + "&api_secret=" + Facepp_config.api_secret;
            if (face_id != "") sendUrl += "&face_id=" + face_id;
            if (group_id != "") sendUrl += "&group_id=" + group_id;
            if (person_name != "") sendUrl += "&person_name=" + person_name;
            if (tag != "") sendUrl += "&tag=" + tag;
            return create(sendUrl);
        }

        public IPersonCreated Create_InfoFromId(string[] face_idArr, string[] group_idArr, string person_name = "", string tag = "")
        {
            return Create_InfoFromId(String.Join(",", face_idArr), String.Join(",", group_idArr), person_name, tag);
        }

        IPersonCreated Create_InfoFromName(string face_id = "", string group_name = "", string person_name = "", string tag = "")
        {
            string sendUrl = CREATE_URL + "?api_key=" + Facepp_config.api_key + "&api_secret=" + Facepp_config.api_secret;
            if (face_id != "") sendUrl += "&face_id=" + face_id;
            if (group_name != "") sendUrl += "&group_name=" + group_name;
            if (person_name != "") sendUrl += "&person_name=" + person_name;
            if (tag != "") sendUrl += "&tag=" + tag;
            return create(sendUrl);
        }
      
        public IPersonCreated Create_InfoFromName(string[] face_ids, string[] group_names, string person_name = "", string tag = "")
        {
            return Create_InfoFromName(String.Join(",", face_ids), String.Join(",", group_names), person_name, tag);
        }


        private IDeleteState detele(string sendUrl)
        {
            try
            {
                string json = HttpHelper.CreateGetHttpText(sendUrl);
                object obj = Json.Deserialize(json);
                IDeleteState state = new DeleteState();
                state.CopyObject(obj as Dictionary<string, object>);
                return state;
            }
            catch (Exception)
            {

                // throw;
            }
            return null;
        }
        IDeleteState Detele_FromName(string person_name)
        {
            string sendUrl = DELETE_URL + "?api_key=" + Facepp_config.api_key + "&api_secret=" + Facepp_config.api_secret;
            sendUrl += "&person_name=" + person_name;
            return detele(sendUrl);
        }

        public IDeleteState Detele_FromName(string[] person_nameArr)
        {
            string faceset_name = String.Join(",", person_nameArr);
            return Detele_FromName(faceset_name);
        }

       IDeleteState Detele_FromId(string person_id)
        {
            string sendUrl = DELETE_URL + "?api_key=" + Facepp_config.api_key + "&api_secret=" + Facepp_config.api_secret;
            sendUrl += "&person_id=" + person_id;
            return detele(sendUrl);
        }

        public IDeleteState Detele_FromId(string[] person_idArr)
        {
            return Detele_FromId(String.Join(",", person_idArr));
        }



        private IAddedState added(string sendUrl)
        {
            try
            {
                string json = HttpHelper.CreateGetHttpText(sendUrl);
                object obj = Json.Deserialize(json);
                IAddedState state = new AddedState();
                state.CopyObject(obj as Dictionary<string, object>);
                return state;
            }
            catch (Exception)
            {

                //  throw;
            }
            return null;
        }




        public IAddedState Added_FromName(string person_name, string face_id)
        {
            string sendUrl = ADD_URL + "?api_key=" + Facepp_config.api_key + "&api_secret=" + Facepp_config.api_secret;
            sendUrl += "&person_name=" + person_name + "&face_id=" + face_id;
            return added(sendUrl);
        }

        public IAddedState Added_FromName(string person_name, string[] face_idArr)
        {
            return Added_FromName(person_name, String.Join(",", face_idArr));
        }

        public IAddedState Added_FromId(string person_id, string face_id)
        {
            string sendUrl = ADD_URL + "?api_key=" + Facepp_config.api_key + "&api_secret=" + Facepp_config.api_secret;
            sendUrl += "&person_id=" + person_id + "&face_id=" + face_id;
            return added(sendUrl);
        }

        public IAddedState Added_FromId(string person_id, string[] face_idArr)
        {
            return Added_FromId(person_id, String.Join(",", face_idArr));
        }



        private IRemovedState removed(string sendUrl)
        {
            try
            {
                string json = HttpHelper.CreateGetHttpText(sendUrl);
                object obj = Json.Deserialize(json);
                IRemovedState state = new RemovedState();
                state.CopyObject(obj as Dictionary<string, object>);
                return state;
            }
            catch (Exception)
            {

                //  throw;
            }
            return null;

        }

       IRemovedState Removed_FromName(string person_name, string face_id)
        {
            string sendUrl = REMOVE_URL + "?api_key=" + Facepp_config.api_key + "&api_secret=" + Facepp_config.api_secret;
            sendUrl += "&person_name=" + person_name + "&face_id=" + face_id;
            return removed(sendUrl);
        }

        public IRemovedState Removed_FromName(string person_name, string[] face_ids)
        {
            return Removed_FromId(person_name, String.Join(",", face_ids));
        }

       IRemovedState Removed_FromId(string person_id, string face_id)
        {
            string sendUrl = REMOVE_URL + "?api_key=" + Facepp_config.api_key + "&api_secret=" + Facepp_config.api_secret;
            sendUrl += "&person_id=" + person_id + "&face_id=" + face_id;
            return removed(sendUrl);
        }

        public IRemovedState Removed_FromId(string person_id, string[] face_ids)
        {
            return Removed_FromId(person_id, String.Join(",", face_ids));
        }

        public IRemovedState Removed_FromName(string person_name)
        {
            string sendUrl = REMOVE_URL + "?api_key=" + Facepp_config.api_key + "&api_secret=" + Facepp_config.api_secret;
            sendUrl += "&person_name=" + person_name + "&face_id=all";
            return removed(sendUrl);
        }

        public IRemovedState Removed_FromId(string person_id)
        {
            string sendUrl = REMOVE_URL + "?api_key=" + Facepp_config.api_key + "&api_secret=" + Facepp_config.api_secret;
            sendUrl += "&person_id=" + person_id + "&face_id=all";
            return removed(sendUrl);
        }


        private IPerson set_info(string sendUrl)
        {
            try
            {
                string json = HttpHelper.CreateGetHttpText(sendUrl);
                object obj = Json.Deserialize(json);
                IPerson b = new Person();
                b.CopyObject(obj as Dictionary<string, object>);
                return b;
            }
            catch (Exception)
            {

                //  throw;
            }
            return null;
        }


        public IPerson SetInfo_FromId(string person_id, string name = "", string tag = "")
        {
            string sendUrl = SETINFO_URL + "?api_key=" + Facepp_config.api_key + "&api_secret=" + Facepp_config.api_secret;
            sendUrl += "&person_id=" + person_id;
            if (name != "") sendUrl += "&name=" + name;
            if (tag != "") sendUrl += "&tag=" + tag;
            return set_info(sendUrl);   
        }

        public IPerson SetInfo_FromName(string person_name, string name = "", string tag = "")
        {
            string sendUrl = SETINFO_URL + "?api_key=" + Facepp_config.api_key + "&api_secret=" + Facepp_config.api_secret;
            sendUrl += "&person_name=" + person_name;
            if (name != "") sendUrl += "&name=" + name;
            if (tag != "") sendUrl += "&tag=" + tag;
            return set_info(sendUrl);      
        }



        private IPersonGetInfoed  get_info(string sendUrl)
        {
            try
            {
                string json = HttpHelper.CreateGetHttpText(sendUrl);
                object obj = Json.Deserialize(json);
                IPersonGetInfoed info = new PersonGetInfoed();
                info.CopyObject(obj as Dictionary<string, object>);
                return info;
            }
            catch (Exception)
            {

                //  throw;
            }
            return null;
        }


        public IPersonGetInfoed GetInfo_FromId(string person_id)
        {
            string sendUrl = GETINFO_URL + "?api_key=" + Facepp_config.api_key + "&api_secret=" + Facepp_config.api_secret;
            sendUrl += "&person_id=" + person_id;
            return get_info(sendUrl);
        }

        public IPersonGetInfoed GetInfo_FromName(string person_name)
        {
            string sendUrl = GETINFO_URL + "?api_key=" + Facepp_config.api_key + "&api_secret=" + Facepp_config.api_secret;
            sendUrl += "&person_name=" + person_name;
            return get_info(sendUrl);
        }
    }
}
